package com.jimmieran.myshoppriceservice.myshoppriceservice.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jimmieran.myshoppriceservice.myshoppriceservice.mapper.ProductPriceMapper;
import com.jimmieran.myshoppriceservice.myshoppriceservice.model.ProductPrice;
import com.jimmieran.myshoppriceservice.myshoppriceservice.service.ProductPriceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;


@Service
public class ProductPriceServiceImpl implements ProductPriceService {

	@Autowired
	private ProductPriceMapper productPriceMapper;

	@Autowired
	private JedisPool jedisPool;
	
	public void add(ProductPrice productPrice) {
		productPriceMapper.add(productPrice);
		Jedis jedis = jedisPool.getResource();
		jedis.set("product_price_" + productPrice.getProductId(), JSONObject.toJSONString(productPrice));

	}

	//有个优化点：CAP（cache aside pattern），但是还是看具体数据业务读和写的频率。
	//读的时候先删除缓存，然后再更新数据库，这里不用再写回Redis
	//这里为什么不直接set写缓存而是选择直接删除？
	//1、更新缓存的代价更大；
	//2、被更新的缓存不一定每次会被读取，比如1分钟该数据被更新了1000次，但是只被读了1次，那么999次的set都是浪费的
	//等需要读的时候再从数据库拿然后写回Redis。
	//以上只是针对写的频繁度大于读的时候适用，如果写操作很少，可以采取每次写后直接set到Redis。
	public void update(ProductPrice productPrice) {
		Jedis jedis = jedisPool.getResource();
		jedis.del("product_price_" + productPrice.getProductId());
		productPriceMapper.update(productPrice);
	}

	public void delete(Long id) {
		productPriceMapper.delete(id);
		ProductPrice productPrice = this.findById(id);
		Jedis jedis = jedisPool.getResource();
		jedis.del("product_price_" + productPrice.getProductId());
	}

	//有个优化点：CAP（cache aside pattern）
	//1、这里先从Redis里查询，如果没有到MySQL查询，将查询到的结果写回Redis
	//2、这里就有一个数据更新时数据库和Redis双写不一致的问题，采用内存队列串行化执行解决方案
	public ProductPrice findById(Long id) {
		return productPriceMapper.findById(id);
	}

}
